#include<iostream>
#include<fstream>
#include<string>
#include<cctype>
#include<vector>
using namespace std;

struct Token
{
    string type; // 令牌类型
    string value; // 令牌值
    int line; // 出现的行号
};

struct Error
{
    int line; // 错误行号
    string msg; // 错误信息
};

//声明函数
void CompUnit(vector<Token> &tokens,vector<Error> &errors);
void FuncDef(vector<Token> &tokens,vector<Error> &errors);
void Param(vector<Token> &tokens,vector<Error> &errors);
void Block(vector<Token> &tokens,vector<Error> &errors);
void Stmt(vector<Token> &tokens,vector<Error> &errors);
void Expr(vector<Token> &tokens,vector<Error> &errors);
void LOrExpr(vector<Token> &tokens,vector<Error> &errors);
void LAndExpr(vector<Token> &tokens,vector<Error> &errors);
void RelExpr(vector<Token> &tokens,vector<Error> &errors);
void AddExpr(vector<Token> &tokens,vector<Error> &errors);
void MulExpr(vector<Token> &tokens,vector<Error> &errors);
void UnaryExpr(vector<Token> &tokens,vector<Error> &errors);
void PrimaryExpr(vector<Token> &tokens,vector<Error> &errors);

void lexer(vector<Token> &tokens)
{
    char ch;
    int i = 1;
    while(cin.get(ch))
    {   
        if(ch == EOF)
        {
            tokens.push_back({"EOF", "EOF", i});
            break;
        }
        if(ch == '\n')
        {
            i++;
            continue;
        }
        if(ch == ' ')
        {
            continue;
        }
        else if(ch == '/' && cin.peek() == '/') //注释符号//
        {
            while(cin.get(ch) && (ch != '\n' && ch != EOF));
            i++;
        }
        else if(ch == '/' && cin.peek() == '*') //注释符号/* */
        {
            while(cin.get(ch))
            {
                if(ch == '\n')
                {
                    i++;
                }
                if(ch == '*' && cin.peek() == '/')
                {
                    cin.get(ch);
                    break;
                }
            }
        }
        else if(ch == '_' || (ch >= 'a' &&ch <= 'z') || (ch >= 'A' && ch <= 'Z')) //标识符或关键字
        {
            string str;
            str += ch;
            while(cin.peek() == '_' || (cin.peek() >= 'a' && cin.peek() <= 'z') || (cin.peek() >= 'A' && cin.peek() <= 'Z') || (cin.peek() >= '0' && cin.peek() <= '9'))
            {
                cin.get(ch);
                str += ch;
            }
            if(str == "int" || str == "if" || str == "else" || str == "while" || str == "break" || str == "continue" || str == "return" || str == "void")
            {
                tokens.push_back({str, str, i});
            }
            else
            {
                tokens.push_back({"Ident", str, i});
            }
        }
        // else if(ch == '-' ||(ch >= '0' && ch <= '9')) //整数常量
        // {
        //     string str;
        //     str += ch;
        //     while(cin.peek() >= '0' && cin.peek() <= '9')
        //     {
        //         if(str == "0" || str == "-0") //0开头
        //         {
        //             cout << "Error: Invalid integer constant" << endl;
        //             return 0;
        //         }
        //         cin.get(ch);
        //         str += ch;
        //     }
        //     if(str == "-") //单独的负号->减号
        //     {
        //         cout << i <<":'-':\"-\"" << endl;
        //     }
        //     else
        //     {
        //         cout << i <<":IntConst:\"" << str << "\"" << endl;
        //     }
        //     i++;
        // }
        else if(ch >= '0' && ch <= '9') //整数常量
        {
            string str;
            str += ch;
            while(cin.peek() >= '0' && cin.peek() <= '9')
            {
                if(str == "0") //0开头
                {
                    tokens.push_back({"NUMBER", str, i});
                }
                cin.get(ch);
                str += ch;
            }
            tokens.push_back({"NUMBER", str, i});
        }
        else if(ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '%')
        {
            tokens.push_back({string(1,ch), string(1,ch), i});    
        }
        else if(ch == ';' || ch == ',' || ch == '(' || ch == ')' || ch == '{' || ch == '}')
        {
            tokens.push_back({string(1,ch), string(1,ch), i});
        }
        else if(ch == '|' && cin.peek() == '|')
        {
            cin.get(ch);
            tokens.push_back({"||", "||", i});
        }
        else if(ch == '&' && cin.peek() == '&')
        {
            cin.get(ch);
            tokens.push_back({"&&", "&&", i});
        }
        else if(ch == '<' || ch == '>' || ch == '=' || ch == '!')
        {
            string str;
            str += ch;
            if(cin.peek() == '=')
            {
                cin.get(ch);
                str += ch;
            }
            tokens.push_back({str, str, i});
        }    
    }
    tokens.push_back({"EOF", "EOF", i});
}

// CompUnit → FuncDef+
void CompUnit(vector<Token> &tokens,vector<Error> &errors)
{
    if (tokens.empty() && tokens[0].type != "int" && tokens[0].type != "void")
    {
        errors.push_back({tokens[0].line, "Expected 'int' or 'void' at the beginning"});
        return;
    }
    while (!tokens.empty() && (tokens[0].type == "int" || tokens[0].type == "void"))
    {
        FuncDef(tokens,errors);
    }
}

// FuncDef → ("int" | "void") ID "(" (Param ("," Param)*)? ")" Block
void FuncDef(vector<Token> &tokens,vector<Error> &errors)
{
    if(tokens.empty())
    {
        return;
    }
    Token tok = tokens[0];
    if (tok.type != "int" && tok.type != "void") {
        errors.push_back({tok.line, "Expected 'int' or 'void'"});
        return;
    }
    tokens.erase(tokens.begin()); // 消耗返回类型关键字

    if (tokens.empty() || tokens[0].type != "Ident") {
        errors.push_back({tokens.empty() ? tok.line : tokens[0].line, "Expected function name"});
        return;
    }
    tokens.erase(tokens.begin()); // 消耗函数名

    if (tokens.empty() || tokens[0].type != "(") {
        errors.push_back({tokens.empty() ? tok.line : tokens[0].line, "Expected '('"});
        return;
    }
    tokens.erase(tokens.begin()); // 消耗 '('

    if (!tokens.empty() && tokens[0].type == ",")
    {
        errors.push_back({tokens[0].line, "Unexpected ',' before parameters"});
        tokens.erase(tokens.begin());
    }

    // 参数列表（可能为空）
    if (!tokens.empty() && tokens[0].type == "int") {
        do {
            Param(tokens,errors);
            if (!tokens.empty() && tokens[0].type == ",") {
                tokens.erase(tokens.begin()); // 消耗 ','
            } else {
                break;
            }
        } while (true);
    }

    if (tokens.empty() || tokens[0].type != ")") {
        errors.push_back({tokens.empty() ? tok.line : tokens[0].line, "Expected ')'"});
        return;
    }
    tokens.erase(tokens.begin()); // 消耗 ')'

    // 函数体必须是 Block
    Block(tokens,errors);
}

// Param → "int" ID
void Param(vector<Token> &tokens,vector<Error> &errors)
{
    if(tokens.empty())
    {
        return;
    }
    Token tok = tokens[0];
    if (tokens.empty() || tokens[0].type != "int") {
        errors.push_back({tok.line, "Expected 'int'"});
        return;
    }
    tokens.erase(tokens.begin()); // 消耗 'int'

    if (tokens.empty() || tokens[0].type != "Ident") {
        errors.push_back({tokens.empty() ? tok.line : tokens[0].line, "Expected identifier"});
        return;
    }
    tokens.erase(tokens.begin()); // 消耗ID
}

// Block → "{" Stmt* "}"
void Block(vector<Token> &tokens,vector<Error> &errors)
{
    if(tokens.empty())
    {
        return;
    }
    Token tok = tokens[0];
    if (tokens.empty() || tokens[0].type != "{") {
        errors.push_back({tok.line, "Expected '{'"});
        return;
    }
    tokens.erase(tokens.begin()); // 消耗 '{'

    // 在遇到右大括号或 tokens 结束前反复解析语句
    // 为避免解析函数未消费任何 token 导致无限循环，记录解析前后的 tokens.size() 以判断是否有进展
    while (!tokens.empty() && tokens[0].type != "}") {
        size_t savedSize = tokens.size();
        Stmt(tokens,errors);
        // 解析后如果 tokens 大小没有变化，说明没有消费任何 token -> 跳过当前 token 防止死循环
        if (tokens.size() == savedSize) {
            int line = tokens.empty() ? tok.line : tokens[0].line;
            errors.push_back({line, "语句解析失败，跳过当前 token"});
            // 跳过一个无法识别的 token
            tokens.erase(tokens.begin());
        }
        if(!tokens.empty())
        {
            tok = tokens[0];
        }
    }
    

    if (tokens.empty() || tokens[0].type != "}") {
        errors.push_back({tokens.empty() ? tok.line : tokens[0].line, "Expected '}'"});
        return;
    }
    tokens.erase(tokens.begin()); // 消耗 '}'   
}

/*
Stmt → Block | “;” | Expr “;” | ID “=” Expr “;”
           | “int” ID “=” Expr “;”
           | “if ” “(” Expr “)” Stmt (“else” Stmt)?
           | “while” “(” Expr “)” Stmt
           | “break” “;” | “continue” “;” | “return” Expr “;”
*/
void Stmt(vector<Token> &tokens,vector<Error> &errors)
{
    if(tokens.empty())
    {
        return;
    }
    Token tok = tokens[0];
    if(tok.type == "{")
    {
        Block(tokens,errors);
        return;
    }
    else if(tok.type == ";")
    {
        tokens.erase(tokens.begin()); // 消耗 ';'
        return;
    }
    else if(tok.type == "Ident")
    {
        tokens.erase(tokens.begin()); // 消耗 ID
        if(!tokens.empty() && tokens[0].type == "=")
        {
            tokens.erase(tokens.begin()); // 消耗 '='
            Expr(tokens,errors);
            if(!tokens.empty() && tokens[0].type == ";")
            {
                tokens.erase(tokens.begin()); // 消耗 ';'
            }
            else
            {
                errors.push_back({tokens.empty() ? tok.line : tokens[0].line, "Expected ';'"});
            }
            return;
        }
        else if(!tokens.empty() && tokens[0].type == "(")
        {
            // 函数调用表达式
            tokens.insert(tokens.begin(), tok); // 回退到标识符，作为表达式处理
            Expr(tokens,errors);
            if(!tokens.empty() && tokens[0].type == ";")
            {
                tokens.erase(tokens.begin()); // 消耗 ';'
            }
            else
            {
                errors.push_back({tokens.empty() ? tok.line : tokens[0].line, "Expected ';'"});
            }
            return;
        }
        else
        {
            // 不是赋值，则回退到标识符，作为表达式处理
            tokens.insert(tokens.begin(), tok);

        }
    }
    else if(tok.type == "int")
    {
        tokens.erase(tokens.begin()); // 消耗 'int'
        // 期望至少一个标识符
        if(tokens.empty() || tokens[0].type != "Ident")
        {
            errors.push_back({tokens.empty() ? tok.line : tokens[0].line, "Expected identifier"});
            return;
        }

        // 处理第一个标识符（可能带初始化）
        tokens.erase(tokens.begin()); // 消耗 ID
        if(!tokens.empty() && tokens[0].type == "=")
        {
            tokens.erase(tokens.begin()); // 消耗 '='
            Expr(tokens,errors);
        }

        // 后续以逗号分隔的声明
        while(!tokens.empty() && tokens[0].type == ",")
        {
            // 消耗 ','
            tokens.erase(tokens.begin());

            // 如果逗号后不是标识符，则报错并尝试恢复到下一个逗号或分号或 EOF
            if(tokens.empty() || tokens[0].type != "Ident")
            {
                errors.push_back({tokens.empty() ? tok.line : tokens[0].line, "缺少变量名"});
                while(!tokens.empty() && tokens[0].type != "," && tokens[0].type != ";" && tokens[0].type != "EOF")
                {
                    tokens.erase(tokens.begin());
                }
                if(!tokens.empty() && tokens[0].type == ",")
                {
                    // 继续下一个声明
                    continue;
                }
                else
                {
                    break;
                }
            }

            // 有标识符，处理之
            tokens.erase(tokens.begin()); // 消耗 ID
            if(!tokens.empty() && tokens[0].type == "=")
            {
                tokens.erase(tokens.begin()); // 消耗 '='
                Expr(tokens,errors);
            }
        }

        // 期望以分号结束
        if(!tokens.empty() && tokens[0].type == ";")
        {
            tokens.erase(tokens.begin()); // 消耗 ';'
        }
        else
        {
            errors.push_back({tokens.empty() ? tok.line : tokens[0].line, "expected ';'"});
        }
        return;
    }
    else if(tok.type == "if")
    {
        // 消耗 'if'
        tokens.erase(tokens.begin());

        // 期望 '('
        if (tokens.empty() || tokens[0].type != "(")
        {
            errors.push_back({tokens.empty() ? tok.line : tokens[0].line, "'if' 后应为 '('"});
            // 若下一个是块，则尝试继续解析该块并处理 else
            if (!tokens.empty() && tokens[0].type == "{")
            {
                Stmt(tokens, errors);
                if (!tokens.empty() && tokens[0].type == "else")
                {
                    tokens.erase(tokens.begin()); // 消耗 'else'
                    Stmt(tokens, errors);
                }
            }
            else
            {
                // 跳过到下一个可能的语句开始或关键字以尝试恢复
                while (!tokens.empty())
                {
                    string tt = tokens[0].type;
                    if (tt == "}" || tt == "EOF" || tt == "int" || tt == "if" || tt == "while" ||
                        tt == "break" || tt == "continue" || tt == "return" || tt == "Ident" ||
                        tt == ";" || tt == "{" || tt == "else")
                        break;
                    tokens.erase(tokens.begin());
                }
                if (!tokens.empty() && tokens[0].type == "{")
                {
                    Stmt(tokens, errors);
                    if (!tokens.empty() && tokens[0].type == "else")
                    {
                        tokens.erase(tokens.begin()); // 消耗 'else'
                        Stmt(tokens, errors);
                    }
                }
                else if (!tokens.empty() && tokens[0].type == "else")
                {
                    tokens.erase(tokens.begin()); // 消耗 'else'
                    Stmt(tokens, errors);
                }
            }
            return;
        }

        // 消耗 '('
        tokens.erase(tokens.begin());

        // 解析条件表达式（可能产生错误并记录）
        Expr(tokens, errors);

        // 期望 ')'
        if (tokens.empty() || tokens[0].type != ")")
        {
            errors.push_back({tokens.empty() ? tok.line : tokens[0].line, "条件后应有 ')'"}); 
            // 如果下一个是 '{'，尝试继续解析 if 的语句块并处理 else
            if (!tokens.empty() && tokens[0].type == "{")
            {
                Stmt(tokens, errors);
                if (!tokens.empty() && tokens[0].type == "else")
                {
                    tokens.erase(tokens.begin()); // 消耗 'else'
                    Stmt(tokens, errors);
                }
            }
            else
            {
                // 尝试同步到下一个可能的语句开始位置
                while (!tokens.empty())
                {
                    string tt = tokens[0].type;
                    if (tt == "}" || tt == "EOF" || tt == "int" || tt == "if" || tt == "while" ||
                        tt == "break" || tt == "continue" || tt == "return" || tt == "Ident" ||
                        tt == ";" || tt == "{" || tt == "else")
                        break;
                    tokens.erase(tokens.begin());
                }
                if (!tokens.empty() && tokens[0].type == "{")
                {
                    Stmt(tokens, errors);
                    if (!tokens.empty() && tokens[0].type == "else")
                    {
                        tokens.erase(tokens.begin()); // 消耗 'else'
                        Stmt(tokens, errors);
                    }
                }
                else if (!tokens.empty() && tokens[0].type == "else")
                {
                    tokens.erase(tokens.begin()); // 消耗 'else'
                    Stmt(tokens, errors);
                }
            }
            return;
        }

        // 消耗 ')'
        tokens.erase(tokens.begin());

        // 解析 if 的主体语句
        Stmt(tokens, errors);

        // 可选 else
        if (!tokens.empty() && tokens[0].type == "else")
        {
            tokens.erase(tokens.begin()); // 消耗 'else'
            Stmt(tokens, errors);
        }
        return;
    }
    else if(tok.type == "while")
    {
        tokens.erase(tokens.begin()); // 消耗 'while'
        if(tokens.empty() || tokens[0].type != "(")
        {
            errors.push_back({tokens.empty() ? tok.line : tokens[0].line, "Expected '('"});
            return;
        }
        tokens.erase(tokens.begin()); // 消耗 '('
        Expr(tokens,errors);
        if(tokens.empty() || tokens[0].type != ")")
        {
            errors.push_back({tokens.empty() ? tok.line : tokens[0].line, "Expected ')'"});
            return;
        }
        tokens.erase(tokens.begin()); // 消耗 ')'
        Stmt(tokens,errors);
        return;
    }
    else if(tok.type == "break" || tok.type == "continue")
    {
        tokens.erase(tokens.begin()); // 消耗 'break' 或 'continue'
        if(!tokens.empty() && tokens[0].type == ";")
        {
            tokens.erase(tokens.begin()); // 消耗 ';'
        }
        else
        {
            errors.push_back({tokens.empty() ? tok.line : tokens[0].line, "Break or continue expected ';'"});
        }
        return;
    }
    else if(tok.type == "return")
    {
        tokens.erase(tokens.begin()); // 消耗 'return'
        Expr(tokens,errors);
        if(!tokens.empty() && tokens[0].type == ";")
        {
            tokens.erase(tokens.begin()); // 消耗 ';'
        }
        else
        {
            errors.push_back({tokens.empty() ? tok.line : tokens[0].line, "Return expected ';'"});
        }
        return;
    }
    else
    {
        Expr(tokens,errors);
        if(!tokens.empty() && tokens[0].type == ";")
        {
            tokens.erase(tokens.begin()); // 消耗 ';'
        }
        else
        {
            errors.push_back({tokens.empty() ? tok.line : tokens[0].line, "Expr expected ';"});
        }
        return;
    }
}

// Expr → LOrExpr
void Expr(vector<Token> &tokens,vector<Error> &errors)
{
    LOrExpr(tokens,errors);
}

// LOrExpr → LAndExpr | LOrExpr “||” LAndExpr
void LOrExpr(vector<Token> &tokens,vector<Error> &errors)
{
    LAndExpr(tokens,errors);
    while(!tokens.empty() && tokens[0].type == "||")
    {
        tokens.erase(tokens.begin()); // 消耗 '||'
        LAndExpr(tokens,errors);
    }
}

// LAndExpr → RelExpr | LAndExpr “&&” RelExpr
void LAndExpr(vector<Token> &tokens,vector<Error> &errors)
{
    RelExpr(tokens,errors);
    while(!tokens.empty() && tokens[0].type == "&&")
    {
        tokens.erase(tokens.begin()); // 消耗 '&&'
        RelExpr(tokens,errors);
    }
}

// RelExpr → AddExpr | RelExpr (“<” | “>” | “<=” | “>=” | “==” | “!=”) AddExpr
void RelExpr(vector<Token> &tokens,vector<Error> &errors)
{
    AddExpr(tokens,errors);
    while(!tokens.empty() && (tokens[0].type == "<" || tokens[0].type == ">" || tokens[0].type == "<=" || tokens[0].type == ">=" || tokens[0].type == "==" || tokens[0].type == "!="))
    {
        tokens.erase(tokens.begin()); // 消耗关系运算符
        AddExpr(tokens,errors);
    }
}

// AddExpr → MulExpr | AddExpr (“+” | “-”) MulExpr
void AddExpr(vector<Token> &tokens,vector<Error> &errors)
{
    MulExpr(tokens,errors);
    while(!tokens.empty() && (tokens[0].type == "+" || tokens[0].type == "-"))
    {
        tokens.erase(tokens.begin()); // 消耗加减运算符
        MulExpr(tokens,errors);
    }
}

// MulExpr → UnaryExpr | MulExpr (“*” | “/” | “%”) UnaryExpr
void MulExpr(vector<Token> &tokens,vector<Error> &errors)
{
    UnaryExpr(tokens,errors);
    while(!tokens.empty() && (tokens[0].type == "*" || tokens[0].type == "/" || tokens[0].type == "%"))
    {
        tokens.erase(tokens.begin()); // 消耗乘除模运算符
        UnaryExpr(tokens,errors);
    }
}

// UnaryExpr → PrimaryExpr | (“+” | “-” | “!”) UnaryExpr
void UnaryExpr(vector<Token> &tokens,vector<Error> &errors)
{
    if(!tokens.empty() && (tokens[0].type == "+" || tokens[0].type == "-" || tokens[0].type == "!"))
    {
        tokens.erase(tokens.begin()); // 消耗一元运算符
        UnaryExpr(tokens,errors);
    }
    else
    {
        PrimaryExpr(tokens,errors);
    }
}

// PrimaryExpr → ID | NUMBER | “(” Expr “)” | ID “(” (Expr (“,” Expr)*)? “)”
void PrimaryExpr(vector<Token> &tokens,vector<Error> &errors)
{
    if(tokens.empty())
    {
        return;
    }
    Token tok = tokens[0];
    if(tok.type == "Ident")
    {
        tokens.erase(tokens.begin()); // 消耗 ID
        if(!tokens.empty() && tokens[0].type == "(")
        {
            tokens.erase(tokens.begin()); // 消耗 '('
            if(!tokens.empty() && tokens[0].type != ")")
            {
                do
                {
                    Expr(tokens,errors);
                    if(!tokens.empty() && tokens[0].type == ",")
                    {
                        tokens.erase(tokens.begin()); // 消耗 ','
                    }
                    else
                    {
                        break;
                    }
                } while (true);
            }
            if(tokens.empty() || tokens[0].type != ")")
            {
                errors.push_back({tok.line, "Expected ')'"});
                return;
            }
            tokens.erase(tokens.begin()); // 消耗 ')'
        }
    }
    else if(tok.type == "NUMBER")
    {
        tokens.erase(tokens.begin()); // 消耗 NUMBER
    }
    else if(tok.type == "(")
    {
        // tokens.erase(tokens.begin()); // 消耗 '('
        // Expr(tokens,errors);
        // if(tokens.empty() || tokens[0].type != ")")
        // {
        //     errors.push_back({tok.line, "Expected ')'"});
        //     return;
        // }
        // tokens.erase(tokens.begin()); // 消耗 ')'
        // 先在 tokens 向量中无副作用地前瞻，检查是否在当前 '(' 的顶层出现逗号
        bool commaAtTopLevel = false;
        int depth = 0;
        for (size_t k = 1; k < tokens.size(); ++k)
        {
            const string &tt = tokens[k].type;
            if (tt == "EOF") break;
            if (tt == "(") { ++depth; continue; }
            if (tt == ")")
            {
                if (depth == 0) break; // 找到与当前 '(' 匹配的 ')'
                --depth;
                continue;
            }
            if (tt == "," && depth == 0)
            {
                commaAtTopLevel = true;
                break;
            }
        }
        if (commaAtTopLevel)
        {
            // 报错并尝试快速恢复：消费 '(' 然后跳过到下一个 ')' 或 EOF
            errors.push_back({tok.line, "括号表达式顶层出现逗号，可能缺少函数名"});
            // consume '('
            tokens.erase(tokens.begin());
            int nest = 0;
            while (!tokens.empty() && tokens[0].type != ")" && tokens[0].type != "EOF")
            {
                if (tokens[0].type == "(") { ++nest; tokens.erase(tokens.begin()); continue; }
                if (tokens[0].type == ")")
                {
                    if (nest == 0) break;
                    --nest;
                }
                tokens.erase(tokens.begin());
            }
            if (!tokens.empty() && tokens[0].type == ")") tokens.erase(tokens.begin());
            return;
        }
        // 正常的括号表达式解析
        tokens.erase(tokens.begin()); // consume '('
        Expr(tokens, errors);

        // 如果解析过程中出现顶层逗号，视为错误并恢复
        if (!tokens.empty() && tokens[0].type == ",")
        {
            errors.push_back({tokens[0].line, "括号内不允许顶层逗号，可能缺少函数名"});
            while (!tokens.empty() && tokens[0].type != ")" && tokens[0].type != "EOF")
                tokens.erase(tokens.begin());
        }

        if (tokens.empty() || tokens[0].type != ")")
        {
            errors.push_back({tokens.empty() ? tok.line : tokens[0].line, "缺少右括号 ')'"});
            return;
        }
        tokens.erase(tokens.begin()); // consume ')'
        return;
    }
    else
    {
        errors.push_back({tok.line, "Expected identifier, number, or '('"});
        return;
    }
}


void parser(vector<Token> &tokens, vector<Error> &errors)
{
    CompUnit(tokens,errors);
}

int main()
{
    vector<Token> tokens;
    vector<Error> errors;
    lexer(tokens);
    // for(const auto &token : tokens)
    // {
    //     cout << token.line << ":" << token.type << ":\"" << token.value << "\"" << endl;
    // }
    parser(tokens, errors);
    if(errors.empty())
    {
        cout << "accept" << endl;
    }
    else
    {
        cout << "reject" << endl;
        int a = errors.size();
        for(int i = 0; i < a; i++)
        {
            if(i == 0 || errors[i].line != errors[i-1].line )
            {
               cout << errors[i].line << " " << errors[i].msg << endl; 
            }
        }
    }
    return 0;

}